package com.example.sunnyweather.logic.network

import androidx.lifecycle.liveData
import com.example.sunnyweather.logic.dao.PlaceDao
import com.example.sunnyweather.logic.model.Place
import com.example.sunnyweather.logic.model.Weather
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import java.lang.Exception
import java.lang.RuntimeException
import kotlin.coroutines.CoroutineContext


object Repository {
    //TODO 第一个方案 就是一个一个写
//    fun searchPlaces(query:String) = liveData(Dispatchers.IO){
//        val result = try {
//            val placeResponse = SunnyWeatherNetwork.searchPlaces(query)
//            if (placeResponse.status == "ok"){
//                val places = placeResponse.places
//                Result.success(places)
//            }else{
//                Result.failure(RuntimeException("response status is${placeResponse.status}"))
//            }
//        }catch (e:Exception){
//            Result.failure(e)
//        }
//        emit(result)
//    }
//
//    fun refreshWeather(lng:String,lat:String) = liveData(Dispatchers.IO){
//        val result = try {
//            coroutineScope {
//                val deferredRealtime = async {
//                    SunnyWeatherNetwork.geteRealtimeWather(lng,lat)
//                }
//                val deferredDaily = async {
//                    SunnyWeatherNetwork.getDailyWeather(lng,lat)
//                }
//
//                val realtimeResponse = deferredRealtime.await()
//                val dailyResponse = deferredDaily.await()
//
//                if (realtimeResponse.status == "ok" && dailyResponse.status == "ok"){
//                    val weather = Weather(realtimeResponse.result.realtime,dailyResponse.result.daily)
//                    Result.success(weather)
//                }else{
//                    Result.failure(java.lang.RuntimeException("realtime response status is ${realtimeResponse.status}"+
//                    "daily response status is ${dailyResponse.status}"
//                    ))
//                }
//            }
//        }catch (e:Exception){
//            Result.failure<Weather>(e)
//        }
//        emit(result)
//    }


    fun savePlace(place: Place) = PlaceDao.savePlace(place)
    fun getSavePlace() = PlaceDao.getSavedPlace()
    fun isPlaceSaved() = PlaceDao.isPlaceSaved()


    //todo 第二个方案就是把公共的拿出来使用
    fun searchPlaces(query: String) = fire(Dispatchers.IO) {
        val placeResponse = SunnyWeatherNetwork.searchPlaces(query)
        if (placeResponse.status == "ok") {
            val places = placeResponse.places
            Result.success(places)
        } else {
            Result.failure(RuntimeException("response static is ${placeResponse.status}"))
        }
    }

    fun refreshWeather(lng: String, lat: String) = fire(Dispatchers.IO) {
        coroutineScope {
            val deferredRealtime = async {
                SunnyWeatherNetwork.geteRealtimeWather(lng, lat)
            }
            val deferredDaily = async {
                SunnyWeatherNetwork.getDailyWeather(lng, lat)
            }
            var realtimeResponse = deferredRealtime.await()
            var dailyResult = deferredDaily.await()
            if (realtimeResponse.status == "ok" && dailyResult.status == "ok") {
                var weather = Weather(realtimeResponse.result.realtime, dailyResult.result.daily)
                Result.success(weather)
            } else {
                Result.failure(RuntimeException("realtimeResponse status is ${realtimeResponse.status} dailyResult status is ${dailyResult.status}"))
            }
        }

    }


    private fun <T> fire(context: CoroutineContext, block: suspend () -> Result<T>) =
        liveData(Dispatchers.IO) {
            val result = try {
                block()
            } catch (e: Exception) {
                Result.failure<T>(e)
            }
            emit(result)
        }

}